/*
 * Copyright (C) 2019 C-SKY Microsystems Co., Ltd. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/******************************************************************************
 * @file     test_vpu.c
 * @brief    Encode test case
 * @version  V1.6
 * @date     27. May 2019
 ******************************************************************************/

#include <stdio.h>
#include <assert.h>
#include <time.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdint.h>
#include <aos/aos.h>
#include <ulog/ulog.h>

#include "h264_vpu.h"
#include "video_h264.h"

#define TAG "vh264"

#define MAX_ENCODED_DATA	(100*1024)
#define H264_DUMP_LEN	(1024 * 1024 * 2)
uint8_t g_dump_memory[H264_DUMP_LEN];
int g_dump_memory_offset = 0;

void video_h264_seek_iframe(int timeout_ms)
{
	int ret;

	long long start_time = aos_now_ms();

	while (aos_now_ms() - start_time < timeout_ms) {

		ret = h264_vpu_seek_iframe();
		if (ret == 0) {
			LOGD(TAG, "seek i-frame success");
			return;
		}

		aos_msleep(20);
	}

	if (aos_now_ms() - start_time >= timeout_ms) {
		LOGD(TAG, "seek timeout");
	}
}

#ifdef dump_h264_file
#define H264_DUMP_TEST_LEN	(1024*1024 * 2)
int g_h264_dump_offset = 0;
uint8_t g_h264_dump[H264_DUMP_TEST_LEN];
#endif

int video_h264_get_data(uint8_t *encoded_data, int max_len, int *is_iframe, long long *time_stamp)
{
	h264_frame_type_e type;
	int ret;

	ret = h264_vpu_get_frame(&type, encoded_data, max_len, time_stamp);
	if (ret > 0 && is_iframe) {
		*is_iframe = type == H264_TYPE_IFRAME;
	}

#ifdef dump_h264_file
	if (ret > 0 && g_h264_dump_offset + ret <= H264_DUMP_TEST_LEN) {
		if (g_h264_dump_offset == 0) {
			printf("**********    dump start		  **************\n");
		}

		memcpy(g_h264_dump + g_h264_dump_offset, encoded_data, ret);
		g_h264_dump_offset += ret;
	}
#endif

	return ret;
}
extern void h264_vpu_get_frame_done(void);
void video_h264_get_data_done(void)
{
	h264_vpu_get_frame_done();
}

void video_h264_init(void)
{
	h264_vpu_init();

	h264_vpu_encode_start();
}

int video_h264_unit_test()
{
	uint8_t *encoded_data = aos_malloc_check(100 * 1024);
	int len = 0;
	int ret = 0;
	int is_iframe;

	h264_vpu_init();

	h264_vpu_encode_start();

	for (int i = 0; i < 1000; i++) {
		ret = video_h264_get_data(encoded_data, 100*1024, &is_iframe, NULL);
		if (ret == 0) {
			if (len <= 0) {
				LOGE(TAG, "data len err %d", len);
			} else {
				if (g_dump_memory_offset + len <= H264_DUMP_LEN) {
					memcpy (g_dump_memory + g_dump_memory_offset, encoded_data, len);
					g_dump_memory_offset += len;
				}
			}

			h264_vpu_get_frame_done();
		}

		if (i == 55) {
			LOGD(TAG, "seek i-frame");
			video_h264_seek_iframe(1100);
		}

		aos_msleep(20);
	}

	aos_free(encoded_data);
	printf("video_h264_unit_test end\n");
	return 0;
}